#ifndef ELEMENTS_ELEMENT_H
#define ELEMENTS_ELEMENT_H

#include <memory>
#include <ostream>
#include <shared_mutex>
#include <string>
#include <vector>

#include "common/more/json.h"

#include "element_type.hpp"

namespace Elements
{

struct Element
{
    Element() = default;
    Element(const Element& other);
    virtual ~Element() = default;

    // -- Интерфейс элемента -- //

    virtual bool isSame(Element* const other) const = 0;

    std::string toJsonString(bool isPretty = false) const;

    virtual Common::Json toJson() const = 0;
    virtual void fromJson(const Common::Json& json) = 0;

    virtual Element* clone() const = 0;
    virtual ElementType elementType() const = 0;

    // -- Интерфейс данных -- //

    unsigned id() const;
    void setId(unsigned value);

protected:
    mutable std::shared_mutex m_lock;
    unsigned m_id = 0;
};

typedef std::shared_ptr<Element> ElementPtr;
typedef std::vector<ElementPtr> Elements;

std::ostream& operator<<(std::ostream& out, const Element* const element);

} // namespace Elements

#endif // ELEMENTS_ELEMENT_H
